package org.ucas.faker.web.controller;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ModelAndView;
import org.ucas.faker.web.utils.model.RawPatent;
import org.ucas.faker.web.dto.CarryDto;
import org.ucas.faker.web.dto.DepotView;
import org.ucas.faker.web.dto.PageDto;
import org.ucas.faker.web.dto.ResponseDto;
import org.ucas.faker.web.entity.Depot;
import org.ucas.faker.web.entity.User;
import org.ucas.faker.web.exceptions.BadRequestException;
import org.ucas.faker.web.exceptions.ForbiddenException;
import org.ucas.faker.web.exceptions.RestException;
import org.ucas.faker.web.utils.model.Coordinator;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;

@SuppressWarnings("unchecked")
@Controller
public class DepotController extends BaseController {

  @RequestMapping(value = "/depots", method = RequestMethod.POST)
  @ResponseBody
  public CarryDto<Depot> create(@RequestParam(value = "name") String name) {
    try {
      Depot depot = depotService.create(currentUserId(),name);
      context().depotId = depot.getId();
      return CarryDto.<Depot>of(depot);
    } catch (RestException e) {
      return new CarryDto<Depot>(e.errCode.status,e.errCode.message,null);
    }
  }

  @RequestMapping(value = "/depots/patents", method = RequestMethod.POST)
  @ResponseBody
  public ResponseDto patents(@RequestParam(value = "depotId") Long depotId,
                             @RequestParam(value = "patents")List<Long> patents,
                             @RequestParam(value = "op", defaultValue = "add") String op,
                             @RequestParam(value = "target", defaultValue = "1") Integer target) {
    if(depotId == null) depotId = currentDepotId();
    Depot depot = depotId == null? null : depotService.load(depotId);
    if(depot == null) throw BadRequestException.DEPOT_NOT_EXISTS;
    if(depot.getOwner().equals(currentUserId()))
      throw ForbiddenException.UNPRIVILEGED;

    if(op.equals("add")) {
      depotService.addPatents(depotId,patents);
    } else if(op.equals("rm"))  depotService.removePatents(depotId,patents);
    else if(op.equals("select")) depotService.selectPatents(patents,depotId,target);
    else throw ForbiddenException.FORBIDDEN;

    return ResponseDto.OK;
  }
  @RequestMapping(value = "/depots/save/to/depot", method = RequestMethod.POST)
  @ResponseBody
  public ResponseDto saveToDepot(@RequestParam(value = "depotId") Long depotId,
                             @RequestParam(value = "patents") List<String> patentsId,
                             @RequestParam(value = "op", defaultValue = "add") String op,
                             @RequestParam(value = "target", defaultValue = "1") Integer target) {
	
	List<Long> patents = new LinkedList<>();  
	for(String each : patentsId) {
		RawPatent p = wxClient.detail(each);
		Long id = patentService.create(p);
		patents.add(id);
	}
	
    if(depotId == null) depotId = currentDepotId();
    Depot depot = depotId == null? null : depotService.load(depotId);
    if(depot == null) throw BadRequestException.DEPOT_NOT_EXISTS;
    if(!depot.getOwner().equals(currentUserId()))
      throw ForbiddenException.UNPRIVILEGED;

    if(op.equals("add")) {
      depotService.addPatents(depotId,patents);
    } else if(op.equals("rm"))  depotService.removePatents(depotId,patents);
    else if(op.equals("select")) depotService.selectPatents(patents,depotId,target);
    else throw ForbiddenException.FORBIDDEN;
    return ResponseDto.OK;
  }


  @RequestMapping(value = "/depots/upload",method = RequestMethod.POST)
  @ResponseBody
  public ResponseDto upLoadDoc(HttpServletRequest request, HttpServletResponse response) throws IOException, InvalidFormatException {

    CommonsMultipartResolver multipartResolver=new CommonsMultipartResolver(request.getSession().getServletContext());
    if(multipartResolver.isMultipart(request))
    {

      MultipartHttpServletRequest multiRequest=(MultipartHttpServletRequest)request;
      MultipartFile file = multiRequest.getFile(multiRequest.getFileNames().next());
      String realPath = Coordinator.fileBasePath+currentDepotId()+"/"+Coordinator.exlPath;
      File realPathDirectory = new File(realPath);
      if (realPathDirectory == null || !realPathDirectory.exists()) {
        realPathDirectory.mkdirs();
      }
      String fileName = null;
      if(file!=null)
      {
        UUID uuid = UUID.randomUUID();
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")).toLowerCase();
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");//设置日期格式
//        fileName =(df.format(new Date()))+uuid.toString()+suffix;
        fileName = "patents.xls";
        File uploadFile = new File(realPathDirectory.getPath() + "/" + fileName);
        //File uploadFile = new File(realPathDirectory.getPath() + "/" + "test.pdf");
        String name = file.getOriginalFilename().substring(0,file.getOriginalFilename().lastIndexOf("."));
        file.transferTo(uploadFile);

       // TODO
      }
    }
    return ResponseDto.OK;
  }
  
  
  
  @RequestMapping(value = "/depots/mydepots.html",method = RequestMethod.GET)
  public ModelAndView mydepotshow() {
    User user = currentUser();
    if(user == null) {
      user = userService.findByAccount("root");
      context().userId = user.getId();
    }
    ModelAndView view = new ModelAndView("/depots/mydepots");
    if(currentUserId() != null)
      view.addObject("user",user);

    return view;
  }
  @RequestMapping(value = "/depots/searchquery.html",method = RequestMethod.GET)
  public ModelAndView searchqueryshow() {
    User user = currentUser();
    if(user == null) {
      user = userService.findByAccount("root");
      context().userId = user.getId();
    }
    ModelAndView view = new ModelAndView("/depots/searchquery");
    if(currentUserId() != null)
      view.addObject("user",user);

    return view;
  }
  @RequestMapping(value = "/depots/mark.html",method = RequestMethod.GET)
  public ModelAndView mark() {
    User user = currentUser();
    if(user == null) {
      user = userService.findByAccount("root");
      context().userId = user.getId();
    }
    ModelAndView view = new ModelAndView("/depots/mark");
    if(currentUserId() != null)
      view.addObject("user",user);

    return view;
  }
  @RequestMapping(value = "/depots/analysis.html",method = RequestMethod.GET)
  public ModelAndView analysis() {
    User user = currentUser();
    if(user == null) {
      user = userService.findByAccount("root");
      context().userId = user.getId();
    }
    ModelAndView view = new ModelAndView("/depots/analysis");
    if(currentUserId() != null)
      view.addObject("user",user);

    return view;
  }
  @RequestMapping(value = "/depots/report.html",method = RequestMethod.GET)
  public ModelAndView report() {
    User user = currentUser();
    if(user == null) {
      user = userService.findByAccount("root");
      context().userId = user.getId();
    }
    ModelAndView view = new ModelAndView("/depots/report");
    if(currentUserId() != null)
      view.addObject("user",user);
    return view;
  }

  @RequestMapping(value = "/depots/getmydepots", method = RequestMethod.POST)
  @ResponseBody
  public PageDto<DepotView> getMyDepots(
          @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
          @RequestParam(value = "pageSize", required = false) Integer pageSize){
	    User user = currentUser();
	    if(user == null) {
	      user = userService.findByAccount("root");
	      context().userId = user.getId();
	    }
	    if(pageNumber==null) pageNumber = 0;
	    if(pageSize==null) pageSize = 10;
	  List<Depot> list = depotService.list(user.getId());
	  List<DepotView> res = new ArrayList<>(list.size());
	  for(Depot d :list){
		  res.add(new DepotView(d,depotService.countByDepotId(d.getId())));
	  }
	  //System.out.println(depotService.countByDepotId(1));
	  //System.out.println(list.size()+" \t "+pageNumber+" \t "+pageSize);
	  return PageDto.ofList(res, res.size(), pageNumber, pageSize);
  }
  @RequestMapping(value = "/depots/getallmydepots", method = RequestMethod.POST)
  @ResponseBody
  public CarryDto<String> getAllMyDepots(){
	    User user = currentUser();
	    if(user == null) {
	      user = userService.findByAccount("root");
	      context().userId = user.getId();
	    }
	    
	  List<Depot> list = depotService.list(user.getId());
	  
	  
	  //System.out.println(depotService.countByDepotId(1));
	  //System.out.println(list.size()+" \t "+pageNumber+" \t "+pageSize);
	  return CarryDto.of(list);
  }
  @RequestMapping(value = "/depots/updateMyDepotName", method = RequestMethod.POST)
  @ResponseBody
  public void updateMyDepots(@RequestParam(value = "id", required = false) Integer id,
          @RequestParam(value = "name", required = false) String name){
	    User user = currentUser();
	    if(user == null) {
	      user = userService.findByAccount("root");
	      context().userId = user.getId();
	    }
	    
	  Depot dpt = depotService.load(id);
	  dpt.setName(name);
	  depotService.persist(dpt);
	  
  }
  
  @RequestMapping(value = "/depots/deleteMyDepot", method = RequestMethod.POST)
  @ResponseBody
  public void deleteMyDepots(@RequestParam(value = "id", required = false) Integer id){
	    User user = currentUser();
	    if(user == null) {
	      user = userService.findByAccount("root");
	      context().userId = user.getId();
	    }
	    
	  depotService.delete(id);
	  
  }
}
